#ifndef MXPBASIC_H
#define MXPBASIC_H

typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned int uint16_t;
typedef signed int int16_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;

#define TOKEN_NONE 0

#define TOKEN_VAR 1
#define TOKEN_STR 2
#define TOKEN_NUM 3

#define TOKEN_LP 10  // (
#define TOKEN_RP 11  // )
#define TOKEN_ADD 12 // +
#define TOKEN_SUB 13 // -
#define TOKEN_MUL 14 // *
#define TOKEN_DIV 15 // /

#define TOKEN_IF 20     // IF
#define TOKEN_THEN 21   // THEN
#define TOKEN_PRINT 22  // PRINT
#define TOKEN_GOTO 23   // GOTO
#define TOKEN_INPUT 24  // INPUT
#define TOKEN_GOSUB 25  // GOSUB
#define TOKEN_LET 26    // LET
#define TOKEN_END 27    // END
#define TOKEN_RETURN 28 // RETURN
#define TOKEN_REM 29    // REM

#define TOKEN_EQ 30  // =
#define TOKEN_LT 31  // <
#define TOKEN_GT 32  // >
#define TOKEN_LE 33  // <=
#define TOKEN_GE 34  // >=
#define TOKEN_NEQ 35 // <>

#define TOKEN_EOL 40 // \n

#define TOKEN_COMMA 41 // ,

#define TOKEN_RUN 50  // RUN
#define TOKEN_LIST 51 // LIST

#define TOKEN_SYNTAX 99

uint8_t getkey();
void putkey(uint8_t c);

void io_reset();
uint8_t io_getchar();
void io_putchar(uint8_t c);

void putstr(uint8_t *str);
void putnum_u(uint16_t num);
void putnum(int16_t num);

uint16_t str_len(uint8_t *str);
uint8_t str_eq(uint8_t *str1, uint8_t *str2);

void syntax_error();
void run_error();

uint8_t next_code_char();
uint8_t next_char();
uint8_t next_token();

void move_left(uint16_t pos, uint16_t offset);
void move_right(uint16_t pos, uint16_t offset);
void copy_line(uint16_t pos, uint16_t len);
void insert_line(uint16_t line, uint8_t len);
void read_line(uint16_t line);

uint16_t next_line_pos(uint16_t pos);
uint16_t line_num(uint16_t pos);
uint16_t line_len(uint16_t pos);

int16_t eval_expr3();
int16_t eval_expr2();
int16_t eval_expr1();
int16_t eval_expr();

void run_print();
void run_statement();
void run_input();
void run_let();
void run_if();
void run_goto();
void run_gosub();
void run_return();

void run();
void list();

#endif // MXPBASIC_H
